#ifndef QUEUE_H
#define QUEUE_H

#include <pthread.h>

//#define DEBUG_PACKETNO
/******************************************************************************
  enum declaration
 ******************************************************************************/
typedef enum QueType{
	REALTIME_FIRST = 0,		/* Data real time first */
	COMPLETE_FIRST,		/* Data completion first */
	UNKNOWN_TYPE			/* Unknow type */
}QueType;

/******************************************************************************
  Structure declaration
 ******************************************************************************/
typedef struct AVPacket{
	uint8_t *data;			/* Data packet pointer */
	int   size;				/* Data packet size */
#ifdef DEBUG_PACKETNO
	int   number;			/* Data packet number */
#endif /* DEBUG_PACKETNO */
} AVPacket;

typedef struct node {
	/* previous node pointer */
	struct node* last;
	/* Next node pointer */
	struct node* next;
	void* data;
}node_t;

typedef struct queue {
	pthread_mutex_t mutex;	/* mutex, for mutual exclusion */
	pthread_cond_t condv;		/* condition flag, for synchronizing */
	node_t* head;			/* queue head pointer */
	QueType type;			/* queue type */
	/* overflow flag, only valid for real time (0, normal, 1: overflow) */
	int overflow;
	/* max delay packet number, only valid for real time type queue */
	int delay;
	int msize;				/* queue max size, only valid for real time type queue */
	int size;					/* queue current size */
	
	char *pps;				/* vps, sps and pps info(for h264 and h265 ) */
	int ppsL;
	bool ppsB;
}queue_t;

/******************************************************************************
  API declaration
 ******************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif

/* queue_t** q:  save queue structure varaible address[out param]
    QueType type: queue type (real time or completion type)[in param]
    int msize: queue max size, only valid for real type queue[in param]
    int delay: max delay packet number, only valid for real type queue, 
    it value must smaller than size, valid value 1 to msize[in param]
*/
extern int q_init(queue_t** q, QueType type, int msize, int delay);
extern int q_push_head(queue_t* q, void* data);
extern void* q_pop_tail(queue_t* q);
extern int q_size(queue_t* q);
extern void q_abort(queue_t* q, void (*func)(void*));
extern void q_wake(queue_t* q);
extern void q_free(queue_t** q, void (*func)(void*));
extern void free_AVPacket(void* data);

#ifdef __cplusplus
}
#endif
#endif /* QUEUE_H */
